package cn.itcast.cd.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.itcast.cd.dao.IBaseDao;
import cn.itcast.cd.domain.User;
import cn.itcast.cd.query.IQuery;
import cn.itcast.cd.resultPage.ResultPage;


public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {

	private Class<T> clazz;
	
	public BaseDaoImpl() {
		 //获取泛型化的父类
		 ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
		 //获取泛型运行期真实的类型
		 this.clazz = (Class<T>) type.getActualTypeArguments()[0];
	}
	
	
	@Override
	public void save(T t) {
		this.getHibernateTemplate().save(t);
	}

	@Override
	public ResultPage query(final String hql,final Object[] params,final int currentPage,final int pageSize) {
		final ResultPage result = new ResultPage();
		result.setCurrentPage(currentPage);
		
		result.setPageSize(pageSize);
		this.getHibernateTemplate().execute(new HibernateCallback<ResultPage>() {

			@Override
			public ResultPage doInHibernate(Session session) throws HibernateException,
					SQLException {
				System.out.println(hql);
				Query query = session.createQuery(hql);
				
				//晕死,原来使用空上QUERY方法,一错为空.原来 是空上参数这个一定要判断它不为空.只判断长度是不行的.
				if(params!=null && params.length>0){
					for (int i = 0; i < params.length; i++) {
						query.setParameter(i, params[i]);
					}
				}
				
				int count = query.list().size();
				if((currentPage-1)*pageSize>=0){
					query.setFirstResult((currentPage-1)*pageSize);
					
				}
				if(pageSize>0){
					query.setMaxResults(pageSize);
				}
				
				List list = query.list();
				result.setRowCount(count);
				result.setResult(list);
				return result;
			}
		});
		return result;
	}

	@Override
	public void delete(Long id) {
		T t  =(T) this.getHibernateTemplate().get(clazz,id);
		if(t!=null){
			this.getHibernateTemplate().delete(t);			
		}
	}

	@Override
	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}

	@Override
	public ResultPage queryEntity(IQuery query) {
		StringBuilder hql =new StringBuilder("SELECT obj FROM "+clazz.getName()+" obj WHERE 1=1") ;
		if(StringUtils.isNotBlank(query.getQuery())){
			hql.append(query.getQuery());
		}
		
		return query(hql.toString(), query.getParams(), query.getCurrentPage(), query.getPageSize());
	}

	/**
	 * 
	 *
	 * @param <T> 这个是传入直接的完整的HQL语句,返回一个LIST集合.如果没有条件,就不跟参数.否则一定要有参数.
	 */
	@Override
	public List<T> queryEntity(final String conditions,final Object[] params){
		
		List<T> list = (List<T>) this.getHibernateTemplate().execute(new HibernateCallback<T>() {

			public T doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(conditions);
				
				if(params!=null && params.length>0){
					for (int i = 0; i < params.length; i++) {
						query.setParameter(i, params[i]);
					}
				}
				return (T) query.list();
			}
			
		});
		
		return list;
	}
	
	/**
	 * 
	 *
	 * @param <T> 传入一个完整的HQL,返回一个唯一的值.
	 */
	@Override
	public Object queryUniqueEntity(final String conditions,final Object[] params){
		
		List<T> list = (List<T>) this.getHibernateTemplate().execute(new HibernateCallback<T>() {
			
			public T doInHibernate(Session session) throws HibernateException,
			SQLException {
				Query query = session.createQuery(conditions);
				
				for (int i = 0; i < params.length; i++) {
					query.setParameter(i, params[i]);
				}
				return (T) query.list();
			}
			
		});
		Object obj =null;
		if(list!=null && list.size()>0){
			obj= list.get(0);
		}
		return obj;
	}
	
	@Override
	public T get(Long id) {
		return (T) this.getHibernateTemplate().get(clazz, id);
	}

}
